package com.david.musicapp;

import android.annotation.SuppressLint;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.util.Log;
import android.widget.RemoteViews;

import androidx.annotation.Nullable;

import com.david.core.event.MyEventBus;
import com.david.core.utils.PreferenceUtils;
import com.david.musicapp.bean.Song;
import com.david.musicapp.event.LoopEvent;
import com.david.musicapp.event.SongPlayStateEvent;
import com.david.musicapp.event.SongPositionEvent;
import com.david.musicapp.event.SongStartEvent;
import com.david.musicapp.utils.SongHelper;
import com.david.musicapp.widget.SongWidget;

import org.jetbrains.annotations.NotNull;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class PlayService extends Service implements MediaPlayer.OnCompletionListener {
    public static final String SONG_KEY = "SONG_KEY";

    public static final String SONG_ACTION_TYPE_KEY = "SONG_ACTION_TYPE_KEY";
    public static final String SONG_ACTION_TYPE_SEEK_KEY = "SONG_ACTION_TYPE_SEEK_KEY";

    public static final int SONG_ACTION_TYPE_LOOP_ALL = 0;
    public static final int SONG_ACTION_TYPE_LOOP_ONE = 1;
    public static final int SONG_ACTION_TYPE_LOOP_RANDOM = 2;
    public static final int SONG_ACTION_TYPE_LOOP_NONE = 3;//普通顺序播放，播放完最后一首不重播
    public static final int SONG_ACTION_TYPE_RESTART = 8;
    public static final int SONG_ACTION_TYPE_PAUSE = 9;
    public static final int SONG_ACTION_TYPE_STOP = 10;
    public static final int SONG_ACTION_TYPE_PREVIOUS = 11;
    public static final int SONG_ACTION_TYPE_NEXT = 12;
    public static final int SONG_ACTION_TYPE_CONTINUE = 16;
    public static final int SONG_ACTION_TYPE_SEEK_TO = 17;
    public static final int SONG_ACTION_TYPE_GET_POSITION = 18;

    //大视图下的控件action
    public static final int SONG_ACTION_TYPE_BIG_NOTIFY_PAUSE = 39;
    public static final int SONG_ACTION_TYPE_BIG_NOTIFY_CONTINUE = 40;
    public static final int SONG_ACTION_TYPE_BIG_NOTIFY_PREVIOUS = 41;
    public static final int SONG_ACTION_TYPE_BIG_NOTIFY_NEXT = 42;

    private Song currentSong = null;

    public static boolean isPlaying = false;
    public static int loopType = PreferenceUtils.Companion.getInstance().getInt("loopType", SONG_ACTION_TYPE_LOOP_ALL);



    private PowerManager.WakeLock mWakeLock = null;



    /**
     * //①raw下的资源：
     * MediaPlayer.create(this, R.raw.test);
     * //②本地文件路径：
     * mp.setDataSource("/sdcard/test.mp3");
     * //③网络URL文件：
     * mp.setDataSource("http://www.xxx.com/music/test.mp3");
     */
    private final MediaPlayer mediaPlayer = new MediaPlayer();
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        mediaPlayer.setOnCompletionListener(this);
//        mediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);




        registerWidgetReceiver();


        PowerManager powerManager = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
        mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "music_powermanager");
        mWakeLock.acquire();
    }

    public void registerWidgetReceiver() {
        SongWidget receiver = new SongWidget();
        IntentFilter filter = new IntentFilter();
        filter.addAction(SongWidget.PANEL_VIEW_CLICK);
        filter.addAction(SongWidget.COLLECTION_VIEW_ACTION);
        filter.addAction(SongWidget.REFRESH_WIDGET);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED);
        } else {
            registerReceiver(receiver, filter);
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent == null) {
            return super.onStartCommand(intent, flags, startId);
        }
        long songId = intent.getLongExtra(SONG_KEY, -1);

        switch (intent.getIntExtra(SONG_ACTION_TYPE_KEY, -1)) {
            case SONG_ACTION_TYPE_LOOP_ALL:
                setLoopType(SONG_ACTION_TYPE_LOOP_ALL);
                break;
            case SONG_ACTION_TYPE_LOOP_ONE:
                setLoopType(SONG_ACTION_TYPE_LOOP_ONE);
                break;
            case SONG_ACTION_TYPE_LOOP_RANDOM:
                setLoopType(SONG_ACTION_TYPE_LOOP_RANDOM);
                break;
            case SONG_ACTION_TYPE_LOOP_NONE:
                setLoopType(SONG_ACTION_TYPE_LOOP_NONE);
                break;
            case SONG_ACTION_TYPE_RESTART:
                startPlay();
                break;
            case SONG_ACTION_TYPE_BIG_NOTIFY_PAUSE:
            case SONG_ACTION_TYPE_PAUSE:
                checkNull(-1);
                pausePlay();
                break;
            case SONG_ACTION_TYPE_STOP:
                stopPlay();
                break;
            case SONG_ACTION_TYPE_BIG_NOTIFY_CONTINUE:
            case SONG_ACTION_TYPE_CONTINUE:
                if (loopStopped) {
                    checkNull(songId);
                    loopStopped = false;
                    startPlay();
                } else {
                    continuePlay();
                }
                break;
            case SONG_ACTION_TYPE_BIG_NOTIFY_NEXT:
            case SONG_ACTION_TYPE_NEXT:
                currentSong = SongHelper.Companion.getInstance().getNext(currentSong.id);
                startPlay();
                break;
            case SONG_ACTION_TYPE_BIG_NOTIFY_PREVIOUS:
            case SONG_ACTION_TYPE_PREVIOUS:
                currentSong = SongHelper.Companion.getInstance().getPrevious(currentSong.id);
                startPlay();
                break;
            case SONG_ACTION_TYPE_SEEK_TO:
                int seekPosition = intent.getIntExtra(SONG_ACTION_TYPE_SEEK_KEY, -1);
                if (seekPosition > 0) {
                    seekTo(seekPosition*1000);
                }
                timeProgress = seekPosition;
                break;
            case SONG_ACTION_TYPE_GET_POSITION:
                MyEventBus.getDefault().post(new SongPlayStateEvent(mediaPlayer.isPlaying()));
                if (currentSong == null) {
                    MyEventBus.getDefault().post(new SongPositionEvent(PreferenceUtils.Companion.getInstance().getLong("lastSongId"), 0, mediaPlayer.isPlaying()));
                } else
                    MyEventBus.getDefault().post(new SongPositionEvent(currentSong.id, mediaPlayer.getCurrentPosition(), mediaPlayer.isPlaying()));
                break;
            default:
                if (songId != -1) {
                    if (currentSong == null || songId != currentSong.id) {
                        currentSong = SongHelper.Companion.getInstance().getSongFromId(songId);
                        stopPlay();
                        startPlay();
                    }
                }
        }

        checkNull(songId);
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        PreferenceUtils.Companion.getInstance().setInt("lastPosition", mediaPlayer.getCurrentPosition());
    }

    private void stopPlay(){
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
        }
        MyEventBus.getDefault().post(new SongPlayStateEvent(false));

        isPlaying = false;

        //更新通知栏
        SongHelper.Companion.getInstance().startForeground(this, currentSong, false);

        updateWidget(true);

        timeProgress = 0;
        mHandler.removeMessages(0);
        mHandler.sendEmptyMessageDelayed(0, 1000);
    }

    private void pausePlay(){
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
            isPlaying = false;
            mHandler.removeMessages(0);

            SongHelper.Companion.getInstance().startForeground(this, currentSong, false);

            MyEventBus.getDefault().post(new SongPlayStateEvent(false));

            updateWidget(true);
        }
        /*事件可能是widget点击过来的，所以在pause时startPlay*/
        else {
            startPlay();
        }
    }

    private void continuePlay(){
        if (currentSong == null) {
            currentSong = SongHelper.Companion.getInstance().getSongFromId(PreferenceUtils.Companion.getInstance().getLong("lastSongId"));
            if (currentSong == null) {
                currentSong = SongHelper.Companion.getInstance().getList().get(0);
            }
            startPlay();
            SongHelper.Companion.getInstance().startForeground(this, currentSong, true);
            updateWidget(true);
            return;
        }
        if (!mediaPlayer.isPlaying()) {
            mediaPlayer.start();
        }
        SongHelper.Companion.getInstance().startForeground(this, currentSong, true);

        MyEventBus.getDefault().post(new SongPlayStateEvent(true));

        isPlaying = true;

        updateWidget(true);


        mHandler.removeMessages(0);
        mHandler.sendEmptyMessageDelayed(0, 1000);
    }


    ExecutorService executorService = Executors.newSingleThreadExecutor();
    private void startPlay(){
//        Log.e("music", "startPlay start " + (currentSong == null));

        if (currentSong == null) {
            return;
        }
        executorService.execute(() -> {
            try {
                mediaPlayer.reset();

                mediaPlayer.setDataSource(currentSong.path);
//            //[3]准备播放
                mediaPlayer.prepare();//
                mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                    @Override
                    public void onPrepared(MediaPlayer mp) {
                        //[4]开始播放
                        mediaPlayer.start();
                    }
                });
//

//            Log.e("music", "startPlay end " + (currentSong == null));
            } catch (Exception e) {
                e.printStackTrace();
            }
        });

        if (currentSong.duration == 0) {
            currentSong.duration = mediaPlayer.getDuration();
        }

        MyEventBus.getDefault().post(new SongStartEvent(currentSong.id, currentSong.name));
        MyEventBus.getDefault().post(new SongPlayStateEvent(true));
        PreferenceUtils.Companion.getInstance().setLong("lastSongId", currentSong.id);

        timeProgress = 0;
        mHandler.removeMessages(0);
        mHandler.sendEmptyMessageDelayed(0, 1000);



        isPlaying = true;

        SongHelper.Companion.getInstance().startForeground(this, currentSong, true);
        updateWidget(true);
    }

    private void reStart(){
        mediaPlayer.start();
    }

    private void seekTo(int seekPosition){
        mediaPlayer.seekTo(seekPosition);
    }

    private void setLoopType(int loopType){
//        if (loopType == SONG_ACTION_TYPE_LOOP_ONE) {
//            mediaPlayer.setLooping(true);
//        } else {
//            mediaPlayer.setLooping(false);
//        }
        PreferenceUtils.Companion.getInstance().setInt("loopType", loopType);
        PlayService.loopType = loopType;
        MyEventBus.getDefault().post(new LoopEvent(loopType));

        //更新通知栏
        if (currentSong != null) {
            SongHelper.Companion.getInstance().startForeground(this, currentSong, mediaPlayer.isPlaying());
        } else {
            Song song = SongHelper.Companion.getInstance().getSongFromId(PreferenceUtils.Companion.getInstance().getLong("lastSongId"));
            if (song != null) {
                SongHelper.Companion.getInstance().startForeground(this, song, mediaPlayer.isPlaying());
            }
        }
        //更新桌面小组件
        updateWidget(true);
    }

    private boolean loopStopped = true;

    @Override
    public void onCompletion(MediaPlayer mp) {
        Log.e("music", "onCompletion " + (currentSong == null));
        if (!isPlaying) {
            return;
        }

        if (loopType == SONG_ACTION_TYPE_LOOP_RANDOM) {
            int position = new Random().nextInt(SongHelper.Companion.getInstance().getList().size());
            currentSong = SongHelper.Companion.getInstance().getList().get(position);
            startPlay();
        } else if (loopType == SONG_ACTION_TYPE_LOOP_ONE) {
            startPlay();
        } else {
            int position = SongHelper.Companion.getInstance().getList().indexOf(currentSong);
            currentSong = SongHelper.Companion.getInstance().getNext(currentSong.id);
            SongHelper.Companion.getInstance().setCurrentId(currentSong.id);
            if (loopType != SONG_ACTION_TYPE_LOOP_NONE || position < (SongHelper.Companion.getInstance().getList().size() - 1)) {
                startPlay();
            } else {
                stopPlay();
                loopStopped = true;
                mHandler.removeMessages(0);
            }
        }
    }


    /**
     *
     * @param updateOtherViews 是否更新除进度条的其他view
     */
    private void updateWidget(boolean updateOtherViews){
        //更新桌面小部件
        AppWidgetManager mgr = AppWidgetManager.getInstance(MusicApplication.Companion.instance());
        ComponentName cn = new ComponentName(MusicApplication.Companion.instance(),SongWidget.class);
        RemoteViews remoteViews = SongWidget.getWidgetView(this, timeProgress, updateOtherViews);
        if (remoteViews == null) {
            return;
        }
//        RemoteViews remoteViews = new RemoteViews(MusicApplication.Companion.instance().getPackageName(), R.layout.song_home_widget);
        mgr.updateAppWidget(cn, remoteViews);
    }

    private void checkNull(long songId){
        if (songId == -1 && currentSong == null && SongHelper.Companion.getInstance().getList().size() > 0) {
            currentSong = SongHelper.Companion.getInstance().getSongFromId(PreferenceUtils.Companion.getInstance().getLong("lastSongId"));
            if (currentSong == null) {
                currentSong = SongHelper.Companion.getInstance().getList().get(0);
            }
        }
    }

    public interface OnTimeProgressListener{
        void onTimeChange(int currentTime);
    }

    /**时间更新逻辑*/
    private int timeProgress = 0;
    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler(Looper.getMainLooper()){
        @Override
        public void handleMessage(@NotNull Message msg) {
            super.handleMessage(msg);
            if (msg.what == 0) {
                if ((timeProgress * 1000) < currentSong.duration) {
                    mHandler.sendEmptyMessageDelayed(0, 1000);
                    if (SongHelper.Companion.getInstance().getOnTimeProgressListeners().size() > 0) {
                        for (OnTimeProgressListener item:SongHelper.Companion.getInstance().getOnTimeProgressListeners()) {
                            item.onTimeChange(timeProgress);
                        }
                    }

                    updateWidget(timeProgress%3 == 0);//3s更新一次widget，防止部分手机更新不及时
                    ++timeProgress;
                }
            }
        }
    };
}
